/*
 * Copyright (C) 2017-2021
 * All rights reserved, Designed By
 * Copyright authorization contact 18814114118
 */
package com.shop.cereshop.agent.interceptor;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.shop.cereshop.agent.page.user.CereAgentUserVO;
import com.shop.cereshop.agent.service.user.CereAgentPrivateService;
import com.shop.cereshop.agent.service.user.CereAgentUserService;
import com.shop.cereshop.commons.config.SecurityProperties;
import com.shop.cereshop.commons.constant.CoReturnFormat;
import com.shop.cereshop.commons.domain.agent.CereAgentPrivate;
import com.shop.cereshop.commons.domain.agent.CereAgentRole;
import com.shop.cereshop.commons.domain.agent.CereAgentUser;
import com.shop.cereshop.commons.result.Result;
import com.shop.cereshop.commons.utils.EmptyUtils;
import com.shop.cereshop.agent.redis.api.UserRedisService;
import com.shop.cereshop.agent.service.user.CereAgentRoleService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@Component
/**
 * 注解方式生成日志对象，指定topic生成对象类名
 */
@Slf4j(topic = "AuthorizationInterceptor")
public class AuthorizationInterceptor extends HandlerInterceptorAdapter {

  public static final String USER = "user";

  @Autowired
  private CereAgentUserService cereAgentUserService;

  @Autowired
  private UserRedisService userRedisService;

  @Autowired
  private SecurityProperties securityProperties;

  @Override
  public boolean preHandle(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response,
      @NotNull Object handler) throws Exception {
    Result<Object> result;
    System.out.println("我执行了");
    // 设置跨域
    setHeader(request, response);

    // 从header中获取内部token
    String token = request.getHeader(securityProperties.getHeader());
    if (!EmptyUtils.isEmpty(token) && token.equals("undefined")) {
      token = "";
    }
    // 如果header中不存在token，则从参数中获取token
    if (StringUtils.isBlank(token)) {
      token = request.getParameter(securityProperties.getHeader());
    }
    // 判断当前请求是否需要认证
    String path = request.getServletPath();
    log.info("uri: {}", path);
    boolean needAuth = securityProperties.isNeedAuth(path);

    PrintWriter writer = null;
    response.setCharacterEncoding("UTF-8");
    response.setContentType("text/html; charset=utf-8");
    // token为空
    if (needAuth && StringUtils.isBlank(token)) {
      try {
        writer = response.getWriter();
        // writer.print("token为空");
        result = new Result<>(CoReturnFormat.USER_NOT_LOGIN);
        writer.println(JSON.toJSONString(result));
        return false;
      } catch (IOException e) {
        log.error("response error", e);
      } finally {
        if (writer != null) {
          writer.close();
        }
      }
    }
    // token不为空 查询用户
    CereAgentUserVO user = null;

    // 第96-110行：改为直接赋值 tempVO
    if (ObjectUtil.isNotEmpty(token)) {
      try {
        Long agentUserId = userRedisService.getAgentUserIdByToken(token);
        if (agentUserId != null) {
          CereAgentUser cereAgentUser = cereAgentUserService.selectByUserId(agentUserId);
          if (cereAgentUser != null) {
            CereAgentPrivate cereAgentPrivate = cereAgentUserService.selectCereAgentUserByIdAndRoleType(
                cereAgentUser.getAgentUserId(),
                cereAgentUser.getLastLoginType());
            // 直接赋值 tempVO，避免使用 BeanUtils.copyProperties
            user = CereAgentUserVO.fromUserAndPrivate(cereAgentUser, cereAgentPrivate);
          }
        }
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
    // 抛出token 异常
    if (needAuth && user == null) {
      try {
        writer = response.getWriter();
        response.setContentType("application/json;charset=UTF-8");
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        result = new Result<>(CoReturnFormat.TOKEN_APPROVE_ERROR);
        writer.println(JSON.toJSONString(result));
        return false;
      } catch (IOException e) {
        log.error("response error", e);
      } finally {
        if (writer != null) {
          writer.close();
        }
      }
    }
    // user存在 设置user
    if (ObjectUtil.isNotNull(user)) {
      // 设置userId到request里，后续根据userId，获取用户信息
      user.setToken(token);
      request.setAttribute(USER, user);
      // long startTime = System.currentTimeMillis();
      // //记录用户在线状态
      // onlineUserService.userOnline(user, token);
      // log.info("耗时{}ms", System.currentTimeMillis() - startTime);
    }
    return true;
  }

  /**
   * 为response设置header，实现跨域
   */
  private void setHeader(HttpServletRequest request, HttpServletResponse response) {
    // 跨域的header设置
    response.setHeader("Access-control-Allow-Origin", request.getHeader("Origin"));
    response.setHeader("Access-Control-Allow-Methods", request.getMethod());
    response.setHeader("Access-Control-Allow-Credentials", "true");
    response.setHeader("Access-Control-Allow-Headers", request.getHeader("Access-Control-Request-Headers"));
    // 防止乱码，适用于传输JSON数据
    response.setHeader("Content-Type", "application/json;charset=UTF-8");
  }
}
